#include "module_base.h"

char    g_convTemp[MAX_TEXT_1024];
wchar_t g_convTempW[MAX_TEXT_1024];

CXBytes::CXBytes()
{
	_bMove = FALSE;
	_data = NULL;
	_length = 0;
}

CXBytes::CXBytes(const CXBytes& bytes)
{
	_bMove = FALSE;
	_data = bytes._data;
	_length = bytes._length;
	((CXBytes&)bytes).move();
}

CXBytes::~CXBytes()
{
	if (!_bMove) free(_data);
}

void CXBytes::operator=(const CXBytes &bytes)
{
	if (!_bMove) free(_data);

	_bMove = FALSE;
	_data = bytes._data;
	_length = bytes._length;
	((CXBytes&)bytes).move();
}

char* CXBytes::Alloc(UINT length)
{
	_length = length;
	_data = (char*)malloc(length);
	_data[length - 1] = 0;
	return _data;
}

//--------------------------------------
CXFile::CXFile()
{
	m_file = NULL;
}

BOOL CXFile::open(const wchar_t* pFileName)
{
	if (0 == _wfopen_s(&m_file, pFileName, L"ab+"))
		return TRUE;
	return FALSE;
}

//打开一个空的文件进行读写。如果该文件存在，其内容将被销毁。
BOOL CXFile::openWrite(const wchar_t* pFileName)
{
	if (0 == _wfopen_s(&m_file, pFileName, L"w+"))
		return TRUE;
	return FALSE;
}

//打开文件, 只读模式
BOOL CXFile::openRead(const wchar_t* pFileName)
{
	if (0 == _wfopen_s(&m_file, pFileName, L"rb"))
		return TRUE;
	return FALSE;
}

//打开文件, 指定打开方式
BOOL CXFile::openEx(const wchar_t* pFileName, const wchar_t* pMode)
{
	if (0 == _wfopen_s(&m_file, pFileName, pMode))
		return TRUE;
	return FALSE;
}

void CXFile::close()
{
	fclose(m_file);
}

//返回实际读取长度
UINT CXFile::readData(void *data, int nLength)
{
	if (-1 == nLength)
		nLength = getLength();
	return fread(data, 1, nLength, m_file);
}

UINT  CXFile::getLength()
{
	long length = 0;
	fseek(m_file, 0, SEEK_END);
	length = ftell(m_file);
	fseek(m_file, 0, SEEK_SET);
	return length;
}
BOOL CXFile::seekBegin()
{
	if(0==fseek(m_file, 0, SEEK_SET))
		return TRUE;
	return FALSE;
}

BOOL CXFile::seekEnd()
{
	if (0 == fseek(m_file, 0, SEEK_END))
		return TRUE;
	return FALSE;
}

BOOL CXFile::seekPos(int offset, int origin)
{
	if (0 == fseek(m_file, offset, origin))
		return TRUE;
	return FALSE;
}

BOOL CXFile::readDataRow(char* data, int nLength)
{
	if (fgets(data, nLength, m_file))
		return TRUE;
	return FALSE;
}

CXBytes CXFile::readDataBytes(int nLength)
{
	if (-1 == nLength)
		nLength = getLength();
	CXBytes  bytes;
	if (nLength > 0)
	{
		char* data = bytes.Alloc(nLength+1);
		fread(data, 1, nLength, m_file);
	}
	return bytes;
}

BOOL CXFile::writeData(const void* data, int nLength)
{
	if(0==fwrite(data, 1, nLength, m_file))
		return FALSE;
	return TRUE;
}

BOOL CXFile::writeText(const wchar_t* data, int nLength)
{
	if (-1 == nLength)  nLength = wcslen(data);
	if (0 == fwrite(data, 1, nLength, m_file))
		return FALSE;
	return TRUE;
}

BOOL CXFile::writeTextA(const char* data, int nLength)
{
	if (-1 == nLength)  nLength = strlen(data);
	if (0 == fwrite(data, 1, nLength, m_file))
		return FALSE;
	return TRUE;
}

//------------------------------------------------
BOOL createFolders(const wchar_t*  pPath)
{
	if (NULL == pPath)return FALSE;
	wchar_t fullPath[MAX_PATH] = { 0 };
	wcscpy_s(fullPath, MAX_PATH, pPath);

	int len = wcslen(fullPath);
	if (!(L'\\' == fullPath[len - 1] || L'/' == fullPath[len - 1]))
	{
		const wchar_t*   pEnd = wcsrchr(fullPath, L'\\');
		if (NULL == pEnd) pEnd = wcsrchr(fullPath, L'/');
		if (NULL == pEnd) return FALSE;

		pEnd = wcschr(pEnd, L'.');
		if (NULL == pEnd)  //末尾是文件夹
		{
			if ((len + 1) >= MAX_PATH) return FALSE;
			fullPath[len] = L'\\';
			fullPath[len + 1] = 0;
		}
	}

	const wchar_t* p = wcsstr(fullPath, L":\\");
	if (NULL == p) p = wcsstr(fullPath, L"://");

	if (NULL == p) return FALSE;
	if (p) p += 2;

	wchar_t buf[MAX_PATH] = { 0 };
	while (*p)
	{
		if (L'\\' == *p || L'/' == *p)
		{
			int len = p - fullPath;
			if (len < 1 || len >= MAX_PATH)
				return FALSE;
			wmemcpy_s(buf, MAX_PATH, fullPath, len);
			if (0 != _waccess_s(buf, 0))
			{
				if (-1 == _wmkdir(buf))
				{
					if (EEXIST != errno)
					{
						return FALSE;
					}
				}
			}
		}
		p++;
	}
	return TRUE;
}


BOOL copyFile(const wchar_t* dest, const wchar_t*  src)
{
	wchar_t  dir[MAX_PATH] = { 0 };
	wmemcpy_s(dir, MAX_PATH, dest, wcslen(dest));
	//PathRemoveFileSpec(dir); 
	if (createFolders(dir))
		return ::CopyFile(src, dest, TRUE);
	return FALSE;
}

//-------------------------------------------------
//UTF8 到 UNICODE
CXText utf8ToW(const char *utf8, int length)
{
	CXText  text;
	int nNeedLen = MultiByteToWideChar(CP_UTF8, 0, utf8, length, NULL, 0);
	if (nNeedLen > 0)
	{
		text.resize(nNeedLen);
		nNeedLen = MultiByteToWideChar(CP_UTF8, 0, utf8, length, (wchar_t*)text.toStr(), nNeedLen);
	}
	return text;
}

//UNICODE 到 UTF8 字节集
CXBytes wToUtf8(const wchar_t *pString, int length)
{
	if (-1 == length) length = wcslen(pString);
	CXBytes  bytes;
	int nNeedLen = WideCharToMultiByte(CP_UTF8, NULL, pString, length, NULL, 0, NULL, NULL);
	if (nNeedLen > 0)
	{
		bytes.Alloc(nNeedLen+1);
		nNeedLen = WideCharToMultiByte(CP_UTF8, NULL, pString, length, (char*)bytes.get(), nNeedLen, NULL, NULL);
	}
	return bytes;
}

CXTextA W2A(const wchar_t* pString, int length)
{
	CXTextA  text;
	if (-1 == length) length = wcslen(pString);
	int nNeedLen = WideCharToMultiByte(CP_ACP, NULL, pString, length, NULL, 0, NULL, NULL);
	if (nNeedLen > 0)
	{	
		text.resize(nNeedLen);
		WideCharToMultiByte(CP_ACP, NULL, pString, nNeedLen, (char*)text.toStr(), nNeedLen, NULL, NULL);
	}
	return text;
}

CXText  A2W(const char* pString, int length)
{
	CXText  text;
	if (-1 == length) length = strlen(pString);
	int nNeedLen = MultiByteToWideChar(CP_ACP, 0, pString, length, NULL,0 );
	if (nNeedLen > 0)
	{
		text.resize(nNeedLen);
		MultiByteToWideChar(CP_ACP, 0, pString, length, (wchar_t*)text.toStr(), nNeedLen);
	}
	return text;
}

const char* W2A_temp(const wchar_t* pString)
{
	g_convTemp[0] = 0;
	if (pString)
	{
		int len = WideCharToMultiByte(CP_ACP, NULL, pString, -1, g_convTemp, MAX_TEXT_1024 - 1, NULL, NULL);
		if (len <= 0)
			return "";
	}
	return g_convTemp;
}

const wchar_t* A2W_temp(const char* pString)
{
	g_convTempW[0] = 0;
	if (pString)
	{
		int len = MultiByteToWideChar(CP_ACP, 0, pString, -1, g_convTempW, MAX_TEXT_1024 - 1);
		if (len <= 0)
			return L"";
	}
	return g_convTempW;
}


const wchar_t* GetTime_temp()
{
	time_t time_;
	time(&time_);

	tm tm_;
	localtime_s(&tm_, &time_);

	wcsftime(g_convTempW, MAX_TEXT_1024, L"%Y-%m-%d %H:%M:%S", &tm_);
	return g_convTempW;
}
